import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';
import 'local_constants.dart';

part 'program_entity.g.dart';

////////////
//生成类
//flutter packages pub run build_runner watch
//

//List<ProgramComponent> storage = [];
//List<ProgramEntity> programEntryList = [];

@JsonSerializable()
class ProgramEntity {
  String? name;
  String? id;
  String? filename;
  String? txt;
  int? index;
  //ProgramComponent component;
  //List<ProgramComponent> componentList;
  ProgramEntity(
      {required this.name,
      required this.id,
      required this.index,
      required this.filename,
      required this.txt});
  factory ProgramEntity.fromJson(Map<String, dynamic> json) =>
      _$ProgramEntityFromJson(json);
  Map<String, dynamic> toJson() => _$ProgramEntityToJson(this);

  static List<ProgramEntity> loadAll({required String filename}) {
    List<ProgramEntity> resultList = [];
    String content = readFile(filename);
    if (content != null && content.length > 2) {
      List list = json.decode(content);
      if (list != null) {
        for (var map in list) {
          resultList.add(ProgramEntity.fromJson(map));
        }
      }
    }
    return resultList;
  }

  static void save(
      {required String filename, List<ProgramEntity>? entityList}) {
    saveFile(json.encode(entityList), filename);
  }
}

@JsonSerializable()
class ProgramComponent {
  String id;
  String parentId;
  String name;
  String imageName;
  String backgroundName;
  //int index;
  // String className;
  List<ProgramComponent>? componentList;
  // ProgramComponent nextComponent;
  // String prevComponentId;
  ProgramComponent? endComponent;
  // bool cannotChange;
  // bool cannotDelete;
  double top;
  double left;
  double width;
  double height;
  int loopCount;
  bool isContainer;
  ProgramComponent(
      {this.endComponent,
      required this.imageName,
      required this.backgroundName,
      required this.id,
      required this.name,
      this.componentList,
      required this.top,
      required this.left,
      required this.width,
      required this.height,
      required this.loopCount,
      required this.parentId,
      required this.isContainer});
  factory ProgramComponent.fromJson(Map<String, dynamic> json) =>
      _$ProgramComponentFromJson(json);
  Map<String, dynamic> toJson() => _$ProgramComponentToJson(this);

  ////customer define
  ProgramComponent? findById(String pid) {
    if (this.id == pid) {
      return this;
    } else if (componentList != null) {
      for (ProgramComponent p in componentList!) {
        ProgramComponent? r = p.findById(pid);
        if (r != null) {
          return p;
        }
      }
    }
    if (endComponent != null && endComponent?.id == pid) {
      return endComponent;
    }
    return null;
  }

  List<ProgramComponent> collectionAllAction() {
    List<ProgramComponent> result = [];
    if (name != 'StartComponent') {
      result.add(this);
    }
    if (componentList != null) {
      for (ProgramComponent p in componentList!) {
        result.addAll(p.collectionAllAction());
      }
    }
    return result;
  }

  List<ProgramComponent>? findComponentListContain(String pid) {
    if (componentList != null) {
      for (ProgramComponent p in componentList!) {
        ProgramComponent? r = p.findById(pid);
        if (r != null) {
          return componentList;
        }
      }
      for (ProgramComponent p in componentList!) {
        List<ProgramComponent>? list = p.findComponentListContain(pid);
        if (list != null) {
          return list;
        }
      }
    }

    return null;
  }

  List<ProgramComponent>? findComponentListEndid(String pid) {
    if (endComponent != null && endComponent?.id == pid) {
      return componentList;
    }
    if (componentList != null) {
      for (ProgramComponent p in componentList!) {
        List<ProgramComponent>? l = p.findComponentListEndid(pid);
        if (l != null) {
          return l;
        }
      }
    }
    return null;
  }

  ProgramComponent _clone() {
    ProgramComponent obj = ProgramComponent(
        endComponent: endComponent,
        imageName: imageName,
        backgroundName: backgroundName,
        id: id,
        name: name,
        top: top,
        left: left,
        width: width,
        height: height,
        loopCount: loopCount,
        parentId: parentId,
        isContainer: isContainer);
    if (componentList != null) {
      List<ProgramComponent> list = [];
      for (ProgramComponent com in componentList!) {
        list.add(com._clone());
      }
      obj.componentList = list;
    }
    return obj;
  }

  // ProgramComponent backup() {
  //   // if(storage.length<0){
  //   //   storage[0] = this;
  //   // }
  //   // storage.add(_clone());
  //   // return storage.last;
  // }

  // ProgramComponent restore([int count = 1]){
  //   if(storage.length>1){
  //     storage.removeLast();
  //   }
  //   return storage.last;
  // }

  // static void empty() {
  //   storage.clear();
  // }

  bool removeId(String currentId) {
    if (componentList != null) {
      //int index = 0;
      for (ProgramComponent p in componentList!) {
        if (currentId == p.id) {
          componentList?.remove(p);
          return true;
        }
      }
      for (ProgramComponent p in componentList!) {
        bool result = p.removeId(currentId);
        if (result) {
          return result;
        }
      }
    }
    //index++;
    return false;

    //   for(ProgramComponent p in componentList){
    //     List list = p.findComponentListContain(pid);
    //     if(list!=null){
    //       return list;
    //     }
    //   }
    // }
  }
}
